在過去二十幾天的文章中,我們討論了單元測試,討論了 Widget Test,不知道有沒有觀眾會好奇,到底我們為什麼要測試?工程師的工作不就是寫程式嗎?測試就交給更專業的 QA 去做就好了啊,QA 肯定更專業,能比我們測出更多問題,何必讓不是測試專業的工程師來做測試呢?今天我們就來聊聊這個話題。
在 The Clean Coder 書中,Uncle Bob 認為開發人員不應該交付有問題的程式,當我們寫好程式之後,我們應該檢查程式有沒沒有問題,無論是手動測試或自動化測試,都應該盡可能的確認程式已經沒有問題之後才交付出去。若我們隨意地寫完程式就交付,QA 可能因為缺陷太多無法測試,只能回報基本的缺陷就退回給開發人員,直到開發人員修復了這些基本缺陷,QA 才能更進一步的測試,如此一來一回,就嚴重影響了產品的進度。在交付軟體之前仔細的檢查,確保軟體內在與外的的品質兼具,這才是專業的表現。
想一想,如果我們日常使用的軟體,使用者用一用就會遇到問題,那這軟體對使用者還有足夠價值嗎?那我們更進一步想的話,如果開發人員交付的軟體是充滿缺陷的,是否也代表著開發人員的產出缺乏價值。程式碼並不等於價值,能真正交到使用者手上,幫使用者解決問題的程式碼才有價值。那我們怎麼知道我們正在交付有價值的東西?我們有測試時,每當我們要交付軟體時,測試會告訴我們軟體是能不能正常運作,我們就能更有信心地知道我們在交付有價值的東西。
或許有人會好奇?那既然工程師都能寫測試了,那我們是不是就不需要 QA 了?雖然開發人員也可以寫測試,但是大多數開發人員都是依照需求來測試,測試正常路徑與非正常路徑。但是隨著軟體越來越複雜,功能與功能的交錯可能會引發意想不到的缺陷,根據不同的功能採取不同的測試策略,能有效找到比較難以發現的問題,這是專業 QA 能做到,而開發人員比較難做到的。當開發人員用自動化測試避免了基本的缺陷,QA 才更有時間能專注在發現難以發現的缺陷,更進一步的提升軟體品質。
測試除了能幫我們驗證程式是否正常運作之外,測試也能幫我設計軟體,測試驅動開發就是一門這樣的技術。在開始寫程式之前,我們先分析需求,把需求拆分成更小任務,寫程式之前,我們先寫測試,用測試決定好這一段時間內要產出的功能是什麼,避免一口氣完成整個需求。然後我們就能朝這個目標前進。在這過程中,自然而然的,我們的程式碼就具備了可測試性。當我們完成第一版後,有程式也有測試,然後我們就能安全的重構,最後得到品質更好的程式。其實測試驅動開發與做事情的態度一樣,我們應該先把事情做對,在把事情做好。
有時候,開發人員也知道要寫測試,但是許多外部因素導致我們不能寫測試,最常見的原因就是開發時間不夠了。老闆總是安排了太多工作,又壓了時程,導致開發人員完成需求就已經時間不夠了,更不用談測試,那我們開怎麼做呢?我們必須熟練各種程式與測試技巧,善用開發工具的快捷鍵,讓用工具幫忙做例行操作,自然而然就有時間寫測試了。
當我們開始寫測試之後,測試是會幫我們節省開發時間的,當功能越來越複雜,協作人員越來越多,程式被改壞的機會也變高,我們可能有大半的時間都浪費在處理 Bug。當我們開始寫測試之後,測試達到一定的量,測試就會反過來節省處理 Bug 的時間。
今天聊了許多應該寫測試的原因,但是我們也知道,或許公司沒有這樣的文化,或許開發時間不夠,或許開發人員沒學過,總總原因造成我們無法寫測試。但是這都不應該是阻止我們寫測試的理由,寫測試並不難,即便現在沒有,我們也可以在之後的開發中一點一點的加入測試,先從 0 到 1,再慢慢的從 1 到 10,到 100,我們才能慢慢從 Bug 海中脫離。